package com.wan37.logic.listener.handler;

import com.wan37.logic.db.AsynDBManager;
import com.wan37.logic.domain.entity.UserDO;
import com.wan37.logic.domain.vo.UserVO;
import com.wan37.logic.global.reference.SpringContextHolder;
import com.wan37.logic.listener.annotation.EventHandler;
import com.wan37.logic.listener.annotation.Listener;
import com.wan37.logic.listener.event.EventType;
import com.wan37.logic.listener.event.user.*;
import com.wan37.logic.service.UserService;
import com.wan37.logic.service.cache.UserServiceCache;
import com.wan37.logic.task.cache.TaskCache;
import com.wan37.logic.task.domain.vo.TaskConfigVO;
import com.wan37.logic.task.domain.vo.TaskVO;
import com.wan37.logic.task.service.TaskService;
import com.wan37.logic.task.util.TaskRouteUtil;
import com.wan37.logic.utils.RouteUtils;
import com.wan37.protobuf.constant.CommonTask;
import com.wan37.protobuf.constant.ShopLabel;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 任务事件监听器
 * @author : luoyong
 * @date : 2020-08-08 15:19
 **/
@Listener
public class TaskListenerHandler {
    private TaskCache taskCache;
    private UserServiceCache userServiceCache;
    private TaskService taskService;
    private TaskRouteUtil taskRouteUtil;
    private UserService userService;
    private AsynDBManager asynDBManager;
    private RouteUtils routeUtils;
    public TaskListenerHandler(){
        this.taskCache = SpringContextHolder.getBean("taskCache");
        this.userServiceCache = SpringContextHolder.getBean("userServiceCache");
        this.taskService = SpringContextHolder.getBean("taskService");
        this.taskRouteUtil = SpringContextHolder.getBean("taskRouteUtil");
        this.userService = SpringContextHolder.getBean("userService");
        this.asynDBManager = SpringContextHolder.getBean("asynDBManager");
        this.routeUtils = SpringContextHolder.getBean("routeUtils");
    }

    @EventHandler(value = EventType.LOGIN)
    public void login(UserLoginEvent userLoginEvent){
        Map<String, TaskVO> map = userServiceCache.getUserServiceMap().get(userLoginEvent.getUserId()).getTaskSonType2TaskVO();
        List<TaskVO> taskVOList = taskService.getTaskVOByUserId(userLoginEvent.getUserId());
        //为空则说明没有初始化，进行初始化然后放到缓存
        if (taskVOList == null ||taskVOList.size() == 0){
            for (TaskConfigVO taskConfigVO : taskCache.getTaskId2TaskConfig().values()){
                if ("0".equals(taskConfigVO.getPreTaskId())){
                    TaskVO taskVO = new TaskVO(taskConfigVO, userLoginEvent.getUserId());
                    map.put(taskVO.getTaskSonType(), taskVO);
                    asynDBManager.distributeWork(userLoginEvent.getUserId(), ()->taskService.save(taskVO));
                }
            }
            taskRouteUtil.sendTaskResponse(CommonTask.GET_ALL_TASK, userLoginEvent.getUserId(), new ArrayList<>(map.values()));
            return;
        }
        //缓存初始化
        for (TaskVO taskVO : taskVOList){
            map.put(taskVO.getTaskSonType(), taskVO);
        }
        taskRouteUtil.sendTaskResponse(CommonTask.GET_ALL_TASK, userLoginEvent.getUserId(), taskVOList);
    }

    @EventHandler(value = EventType.DIALOGUE_NPC)
    public void dialogueNpc(UserDialogueNpcEvent dialogueNpcEvent){
        TaskVO taskVO = userServiceCache.getUserServiceMap().get(dialogueNpcEvent
                .getUserId()).getTaskSonType2TaskVO().get(EventType.DIALOGUE_NPC.value);
        if(!taskCache.getTaskId2TaskConfig().containsKey(taskVO.getTaskId())){
            return;
        }
        TaskConfigVO taskConfigVO = taskCache.getTaskId2TaskConfig().get(taskVO.getTaskId());
        if (dialogueNpcEvent.getNpcId().equals(String.valueOf(taskConfigVO.getNumber()))){
            prizeHandler(dialogueNpcEvent, taskVO, taskConfigVO);
            asynDBManager.distributeWork(dialogueNpcEvent.getUserId(), ()->taskService.update(taskVO));
        }
    }

    @EventHandler(value = EventType.SKILL_MONSTER)
    public void skillMonster(UserSkillMonsterEvent userSkillMonsterEvent){
        numberTotalHandler(userSkillMonsterEvent, EventType.SKILL_MONSTER.value);
    }

    @EventHandler(value = EventType.GET_WEAPONRY)
    public void getWeaponry(UserGetWeaponryEvent userGetWeaponryEvent){
        numberTotalHandler(userGetWeaponryEvent, EventType.GET_WEAPONRY.value);
    }

    @EventHandler(value = EventType.ADD_FRIEND)
    public void addFriend(UserAddFriendEvent userAddFriendEvent){
        numberTotalHandler(userAddFriendEvent, EventType.ADD_FRIEND.value);
    }

    @EventHandler(value = EventType.ADD_TEAM)
    public void addTeam(UserAddTeamEvent userAddTeamEvent){
        numberTotalHandler(userAddTeamEvent, EventType.ADD_TEAM.value);
    }

    @EventHandler(value = EventType.ADD_GOLD)
    public void addGold(UserAddGoldEvent userAddGoldEvent){
        numberTotalHandler(userAddGoldEvent, EventType.ADD_TEAM.value);
    }

    @EventHandler(value = EventType.TRADING)
    public void trading(UserTradingEvent userTradingEvent){
        numberTotalHandler(userTradingEvent, EventType.TRADING.value);
    }
    @EventHandler(value = EventType.PVP_WIN)
    public void pvpWin(UserPvpWin userPvpWin){
        numberTotalHandler(userPvpWin, EventType.PVP_WIN.value);
    }

    @EventHandler(value = EventType.ADD_GUILD)
    public void addGuild(UserAddGuildEvent userAddGuildEvent){
        numberTotalHandler(userAddGuildEvent, EventType.ADD_GUILD.value);
    }

    public void numberTotalHandler(BaseUserEvent baseUserEvent, String value){
        TaskVO taskVO = userServiceCache.getUserServiceMap().get(baseUserEvent
                .getUserId()).getTaskSonType2TaskVO().get(value);
        //总数加一
        taskVO.setTotal(taskVO.getTotal() + 1);
        if(!taskCache.getTaskId2TaskConfig().containsKey(taskVO.getTaskId())){
            asynDBManager.distributeWork(baseUserEvent.getUserId(), ()->taskService.update(taskVO));
            return;
        }
        TaskConfigVO taskConfigVO = taskCache.getTaskId2TaskConfig().get(taskVO.getTaskId());
        //判断是否达到这个任务的要求，达到将任务id改为下一个
        if (taskVO.getTotal() >= taskConfigVO.getNumber()){
            prizeHandler(baseUserEvent, taskVO, taskConfigVO);
        }else {
            taskRouteUtil.sendTaskResponse(CommonTask.UPDATE_TASK, taskVO);
        }
        asynDBManager.distributeWork(baseUserEvent.getUserId(), ()->taskService.update(taskVO));
    }

    /**
     * 奖励处理器
     * @param baseUserEvent
     * @param taskVO
     * @param taskConfigVO
     */
    public void prizeHandler(BaseUserEvent baseUserEvent, TaskVO taskVO, TaskConfigVO taskConfigVO){
        taskVO.setTaskId(taskConfigVO.getNextTaskId());
        //发放奖励以及通知客户端
        if (taskConfigVO.getPrizeType() == ShopLabel.MONEY_TYPE_INGOT){
            UserVO userVO = userServiceCache.getUserServiceMap().get(baseUserEvent.getUserId()).getUserVO();
            userVO.setIngot(userVO.getIngot() + taskConfigVO.getPrizeTotal());
            asynDBManager.distributeWork(baseUserEvent.getUserId(), ()->userService.update(new UserDO(userVO)));
            taskRouteUtil.sendTaskResponse(CommonTask.COMPLETION_TASK, taskVO);
            routeUtils.sendUserVO(userVO);
        }
    }
}
